home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / intrvews / examples.lha / examples / rubberband.C
C/C++ Source or Header  |  1993-07-24  |  4KB  |  154 lines

  1. // From linton@marktwain.rad.sgi.com (Mark Linton)
  2. // Subject: rubberbanding
  3. // Date: Tue, 21 Jul 1992 18:00:37 GMT
  4. // 
  5. // Several people have asked about rubberbanding.  Below is an example
  6. // of a way to do rubberbanding while allowing double-buffering.
  7. // The approach is to have a monoglyph (Selector in the example)
  8. // that assumes its contents are opaque and do not change while rubberbanding
  9. // (the latter restriction could be lifted so long as there was an explicit
  10. // notification that the contents changed).  The example also could be optimized
  11. // a bit by having Selector::drag damage the old and new areas instead
  12. // of damaging the entire area via redraw.
  13.  
  14.  
  15. #include <IV-look/kit.h>
  16. #include <InterViews/brush.h>
  17. #include <InterViews/color.h>
  18. #include <InterViews/display.h>
  19. #include <InterViews/event.h>
  20. #include <InterViews/image.h>
  21. #include <InterViews/input.h>
  22. #include <InterViews/layout.h>
  23. #include <InterViews/raster.h>
  24. #include <InterViews/tiff.h>
  25. #include <InterViews/session.h>
  26. #include <InterViews/style.h>
  27. #include <InterViews/transformer.h>
  28. #include <InterViews/tformsetter.h>
  29. #include <InterViews/window.h>
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32.  
  33. class Selector : public InputHandler {
  34. public:
  35.     Selector(Glyph*, Style*);
  36.     virtual ~Selector();
  37.  
  38.     virtual void draw(Canvas*, const Allocation&) const;
  39.  
  40.     virtual void press(const Event&);
  41.     virtual void drag(const Event&);
  42.     virtual void release(const Event&);
  43. private:
  44.     Brush* brush_;
  45.     Color* color_;
  46.     Coord x0_;
  47.     Coord y0_;
  48.     Coord x1_;
  49.     Coord y1_;
  50.     Coord x2_;
  51.     Coord y2_;
  52.     boolean drawn_;
  53.     boolean overlay_damage_;
  54.     boolean overlay_done_;
  55. };
  56.  
  57. Selector::Selector(Glyph* g, Style* s) : InputHandler(g, s) {
  58.     brush_ = new Brush(0);
  59.     Resource::ref(brush_);
  60.     color_ = new Color(*WidgetKit::instance()->background(), 1.0, Color::Xor);
  61.     Resource::ref(color_);
  62.     drawn_ = false;
  63.     overlay_damage_ = false;
  64.     overlay_done_ = false;
  65. }
  66.  
  67. Selector::~Selector() {
  68.     Resource::unref(brush_);
  69.     Resource::unref(color_);
  70. }
  71.  
  72. void Selector::draw(Canvas* c, const Allocation& a) const {
  73.     if (overlay_damage_) {
  74.     Transformer identity;
  75.     c->push_transform();
  76.     c->transformer(identity);
  77.     if (drawn_) {
  78.         c->rect(x0_, y0_, x1_, y1_, color_, brush_);
  79.     }
  80.     Selector* s = (Selector*)this;
  81.     if (overlay_done_) {
  82.         s->drawn_ = false;
  83.         s->overlay_damage_ = false;
  84.         s->overlay_done_ = false;
  85.     } else {
  86.         c->rect(x0_, y0_, x2_, y2_, color_, brush_);
  87.         s->x1_ = s->x2_;
  88.         s->y1_ = s->y2_;
  89.         s->drawn_ = true;
  90.     }
  91.     c->pop_transform();
  92.     } else {
  93.     InputHandler::draw(c, a);
  94.     }
  95. }
  96.  
  97. void Selector::press(const Event& e) {
  98.     x0_ = e.pointer_x();
  99.     y0_ = e.pointer_y();
  100.     InputHandler::press(e);
  101. }
  102.  
  103. void Selector::drag(const Event& e) {
  104.     x2_ = e.pointer_x();
  105.     y2_ = e.pointer_y();
  106.     overlay_damage_ = true;
  107.     redraw();
  108. }
  109.  
  110. void Selector::release(const Event& e) {
  111.     overlay_damage_ = true;
  112.     overlay_done_ = true;
  113.     redraw();
  114.     InputHandler::release(e);
  115. }
  116.  
  117. static PropertyData props[] = {
  118. //  { "*visual", "TrueColor" },
  119.     { nil }
  120. };
  121.  
  122. static OptionDesc options[] = {
  123.     { nil }
  124. };
  125.  
  126. int main(int argc, char** argv) {
  127.     Session* session = new Session("Ipaste", argc, argv, options, props);
  128.     if (argc == 1) {
  129.     fprintf(stderr, "Usage: %s <file>\n", argv[0]);
  130.     exit(1);
  131.     }
  132.  
  133.     Raster* rast = TIFFRaster::load(argv[1]);
  134.     if (rast == nil) {
  135.     fprintf(stderr, "%s: open tiff image %s failed\n", argv[0], argv[1]);
  136.     exit(1);
  137.     }
  138.  
  139.     Style* style = session->default_display()->style();
  140.     const LayoutKit& layout = *LayoutKit::instance();
  141.     session->run_window(
  142.     new ApplicationWindow(
  143.         layout.flexible(
  144.         new Selector(
  145.             new TransformFitter(new Image(rast)), style
  146.         )
  147.         )
  148.     )
  149.     );
  150. }
  151.  
  152.  
  153.  
  154.